using System;
using System.Collections.Generic;
using MSOffice = Microsoft.Office.Core;

namespace Office.Utility.Toolbar
{
	/// <summary>
	/// Utility class to wrap the management of a custom toolbar on an explorer or inspector window. Once the toolbar
	/// is attached to an explorer or inspector, the toolbar class automatically handles the idiosyncrasies of the 
	/// Explorers and Inspectors, including automatically destroying the toolbar when the window closes.
	/// </summary>
    public sealed class Toolbar : CommandBar
	{
		private MSOffice.MsoBarPosition _position = MSOffice.MsoBarPosition.msoBarTop;
	    readonly List<ToolbarControl> _controls = new List<ToolbarControl>();
	    private int? _top;
	    private int? _left;
	    private int? _rowIndex;
	    private bool? _visible;

	    public MSOffice.MsoBarPosition  Position
		{
			get { return _position; }
			set { _position = value; }
		}

		public IList<ToolbarControl> Controls
		{
			get { return _controls; }
		}

        public Toolbar(string name)
            : base(name)
        {
        }

        public Toolbar(string name, CommandBarWindowType windowType)
            : base(name, windowType)
        {
        }

        public Toolbar(string name, CommandBarWindowType windowType, MSOffice.MsoBarPosition position, 
            int top, int left, int rowIndex, bool visible)
            : base(name, windowType)
        {
            _position = position;
            _top = top;
            _left = left;
            _rowIndex = rowIndex;
            _visible = visible;
        }

		/// <summary>
		/// Attach this toolbar to the specified window
		/// </summary>
		/// <param name="window"></param>
		internal override void Attach(WindowAdapter window)
		{
			//Get the command bars collection from the window. 
			var bars = window.CommandBars;
			if (bars == null)
				throw new ApplicationException("CommandBars property was null");

			//Look for the existance of a commandbar with a matching name already on the window
			MSOffice.CommandBar bar = null;
			foreach (MSOffice.CommandBar b in bars)
			{
			    if (b.Name != Name) continue;
			    bar = b;
			    bar.Position = Position;
			    break;
			}

			//If there is no commandbar  with a matching name, create it
			if (bar == null)
			{
				bar = bars.Add(Name, Position, false, true);
			}

            if (_top != null)
                bar.Top = _top.Value;
            if (_left != null)
                bar.Left = _left.Value;
            if (_rowIndex != null)
                bar.RowIndex = _rowIndex.Value;
            if (_visible != null)
                bar.Visible = _visible.Value;
            
			//Attach the toolbar controls to the window command bar
			foreach (var ctrl in Controls)
				ctrl.Attach(bar, window);

            //Show and enable the toolbar
            ShowCommandBar(window, bar);

            window.SelectionChange += ((sender, args) => ShowCommandBar(window, bar));

			Windows.Add(window);
		}

		/// <summary>
		/// Detach the toolbar from a window that's closing
		/// </summary>
		/// <param name="window"></param>
		internal override void Detach(WindowAdapter window)
		{
            Windows.Remove(window);

		    if (window.CommandBars == null) return;
		    foreach (MSOffice.CommandBar bar in window.CommandBars)
		    {
		        if (bar.Name != Name) continue;
		        bar.Delete();
		    }
		}
	}
}
